using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Threading;
using System.Net;
using System.IO;


namespace SrWinGui
{
    public partial class frmShoutcast : Form
    {
        private int sortColumn = -1;
        private DataTable dt;
        private Thread t;
        private int timeout = 7000;
        string searchType;

        public frmShoutcast()
        {
            InitializeComponent();

            //DataTable with shoutcast Info's
            dt = new DataTable();
            dt.Columns.Add("name", typeof(string));
            dt.Columns.Add("id", typeof(string));
            dt.Columns.Add("br", typeof(string));
            dt.Columns.Add("genre", typeof(string));
            dt.Columns.Add("ct", typeof(string));
            dt.Columns.Add("lc", typeof(string));
            dt.PrimaryKey = new DataColumn[] { dt.Columns["id"] };
        }

        /// <summary>
        /// Download shoutcast station list
        /// </summary>
        /// <param name="parameters"></param>
        private void downloadStationList(object parameters)
        {
            try
            {
                string searchString = (string)parameters;

                //disable genre list while populating data (stupid shoutcast server and it's timeouts)
                StationList.Invoke(new ListItemsDelegate(this.changeComboState));

                //create temp datatable
                DataTable tempDt = dt.Clone();
                tempDt.Rows.Clear();

                //begin xml request
                updateStatus("Connecting...");
                WebRequest wr = WebRequest.Create("http://www.shoutcast.com/sbin/newxml.phtml?" + searchType + "=" + searchString);
                wr.Timeout = timeout;
                XmlTextReader xtr = new XmlTextReader(wr.GetResponse().GetResponseStream());                
                xtr.WhitespaceHandling = WhitespaceHandling.None;

                //begin xml contents reading
                while (xtr.Read())
                {
                    updateStatus("Downloading station list...");
                    if (xtr.NodeType == XmlNodeType.Element && xtr.Name == "station")
                    {
                        //<station name=".977 The Hitz Channel" mt="audio/mpeg" id="1025" br="128" genre="Pop Rock Top 40" ct="&#96;N Sync - Girlfriend" lc="7960"></station>                    
                        xtr.MoveToAttribute("name");
                        string name = xtr.Value;
                        xtr.MoveToAttribute("id");
                        string id = xtr.Value;
                        xtr.MoveToAttribute("br");
                        string br = xtr.Value;
                        xtr.MoveToAttribute("genre");
                        string genre = xtr.Value;
                        xtr.MoveToAttribute("ct");
                        string ct = xtr.Value;
                        xtr.MoveToAttribute("lc");
                        string lc = xtr.Value;
                        tempDt.Rows.Add(new string[] { name, id, br, genre, ct, lc });
                    }
                }

                //check if there is any results
                if (tempDt.Rows.Count == 0)
                {
                    updateStatus("");
                    MessageBox.Show("No stations found", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                updateStatus("Populating stations list...");
                
                //everything is ok, so i can substitute my original datatable with it's temp copy
                dt = tempDt;


                StationList.Invoke(new ListItemsDelegate(this.deleteListItems));
                StationList.Invoke(new ListItemsDelegate(this.addListItems));
                updateStatus("");
            }
            catch (WebException we)
            {
                if (we.Status == WebExceptionStatus.Timeout)
                    MessageBox.Show("Timeout during connection.\nRetry a bit later", "Timeout", MessageBoxButtons.OK, MessageBoxIcon.Information);
                else
                    MessageBox.Show("WebError.\n" + we.Message, "Timeout", MessageBoxButtons.OK, MessageBoxIcon.Information);    
            }
            catch (Exception e)
            {
                MessageBox.Show("Generic Error.\n" + e.Message, "Timeout", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            finally
            {
                updateStatus("");
                StationList.Invoke(new ListItemsDelegate(this.changeComboState));
            }
        }
        /// <summary>
        /// Change of Genre
        /// </summary>
        private void uxGenre_SelectedIndexChanged(object sender, EventArgs e)
        {
            //if my previsous thread is still active, we can kill it since there is another request
            if (t != null && t.IsAlive)
            {
                t.Abort();
            }           
            searchType = "genre";
            t = new Thread(downloadStationList);
            t.Start(uxGenre.Items[uxGenre.SelectedIndex].ToString());
        }
        /// <summary>
        /// Search shoutcast in base name
        /// </summary>
        private void cmdSearch_Click(object sender, EventArgs e)
        {
            if (txtSearch.Text.Length <3)
            {
                MessageBox.Show("Insert text to search (at least 3 characters)", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            //if my previsous thread is still active, we can kill it since there is another request
            if (t != null && t.IsAlive)
                t.Abort();

            searchType = "search";
            t = new Thread(downloadStationList);
            t.Start(txtSearch.Text);
        }
        /// <summary>
        /// Update status strip
        /// </summary>
        /// <param name="text">Status Text</param>
        private void updateStatus(string text)
        {
            MainForm f = (MainForm)this.ParentForm;
            f.SetStatus(text);
        }        
        /// <summary>
        /// Clear contents of listView
        /// </summary>
        private void deleteListItems()
        {
            StationList.Items.Clear();
        }
        private delegate void ListItemsDelegate();

        /// <summary>
        /// Populate station list from datatable
        /// </summary>
        private void addListItems()
        {
            ListViewItem lvi;
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                lvi = new ListViewItem(new string[] { dt.Rows[i]["name"].ToString(), dt.Rows[i]["ct"].ToString(), dt.Rows[i]["br"].ToString(), dt.Rows[i]["genre"].ToString() });
                StationList.Items.Add(lvi);
            }                        
        }
        /// <summary>
        /// Disable search boxes due to problems with shoutcast speed
        /// </summary>
        private void changeComboState()
        {
            uxGenre.Enabled = !uxGenre.Enabled;
            txtSearch.ReadOnly = !txtSearch.ReadOnly;
            cmdSearch.Enabled = !cmdSearch.Enabled;
        }
        private void listView1_Resize(object sender, EventArgs e)
        {
            resizeList();
        }
        private void resizeList()
        {
            int numVisibleRows = StationList.Height/23;
            int extra = 4;
            if (StationList.Items.Count > numVisibleRows)
                extra = 25;

            int totalsize = StationList.Width - 135 - 50-extra;
            StationList.Columns[3].Width = 135;
            StationList.Columns[2].Width = 50;
            StationList.Columns[1].Width = totalsize / 2;
            StationList.Columns[0].Width = totalsize - StationList.Columns[1].Width;
        }

        private void frmShoutcast_Load(object sender, EventArgs e)
        {
            resizeList();
        }

        private void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            // Determine whether the column is the same as the last column clicked.
            if (e.Column != sortColumn)
            {
                // Set the sort column to the new column.
                sortColumn = e.Column;
                // Set the sort order to ascending by default.
                StationList.Sorting = SortOrder.Ascending;
            }
            else
            {
                // Determine what the last sort order was and change it.
                if (StationList.Sorting == SortOrder.Ascending)
                    StationList.Sorting = SortOrder.Descending;
                else
                    StationList.Sorting = SortOrder.Ascending;
            }

            // Call the sort method to manually sort.
            StationList.Sort();

            // Set the ListViewItemSorter property to a new ListViewItemComparer
            this.StationList.ListViewItemSorter = new ListViewItemComparer(e.Column,StationList.Sorting);
        }

        private void listView1_DoubleClick(object sender, EventArgs e)
        {
            DataRow[] dr = dt.Select("name='" + StationList.SelectedItems[0].SubItems[0].Text.Replace("'","''") + "'");            
            //check double station, especialy for sky.Fm <.<
            if (dr.Length != 1)
            {
                dr = dt.Select("name='" + StationList.SelectedItems[0].SubItems[0].Text + "' and ct='" + StationList.SelectedItems[0].SubItems[1].Text + "' and br='" + StationList.SelectedItems[0].SubItems[2].Text + "'");
                //TODO check if there is a risult
            }
            ((MainForm)this.ParentForm).LaunchRipping(dr[0]["id"].ToString());
        }



        
    }
}